<script lang="ts" setup>
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { NButton,  NInput, NInputNumber, NSelect, NSpace, NSwitch, NTag, NTooltip, useDialog, useMessage, NScrollbar } from 'naive-ui'
import axios from 'axios'
import { useRouter, useRoute } from 'vue-router'
import { useBasicLayout } from '@/hooks/useBasicLayout'
import { SvgIcon } from '@/components/common'
import nijiImg from '@/assets/images/niji.png'
import mjImg from '@/assets/images/mj.png'
import { fetchMidjourneyDrawList, fetchMidjourneyPromptList, fetchMidjourneyFullPrompt } from '@/api'
import { fetchDrawTaskAPI, fetchTranslateAPI } from '@/api/mjDraw'
import type { ResData } from '@/api/types'
import { fetchGetMjPromptAssociateApi, fetchGetMjPromptFanyiApi } from '@/api/index'
import Loading from '@/components/base/Loading.vue'
import { useAppStore, useAuthStore } from '@/store'
import { copyText } from '@/utils/format'
import marketImg from '@/assets/market.png'

import cardItem from './components/cardItem.vue'

interface PromptItem {
	status: boolean
	title: string
	isCarryParams: boolean
}

const containerRef = ref<HTMLElement | null>(null)
const router = useRouter()
const route = useRoute()
const authStore = useAuthStore()
const isLogin = computed(() => authStore.isLogin)
const userBalance = computed(() => authStore.userBalance)
const sumDrawMjCount = computed(() => {
  return userBalance.value.sumDrawMjCount || 0
})
const appStore = useAppStore()

const theme = computed(() => appStore.theme)
const loadingTextColor = computed(() => theme.value === 'dark' ? '#fff' : '#000')
const ms = useMessage()
const dialog = useDialog()
const { isMobile } = useBasicLayout()
const uploadUrl = ref(`${import.meta.env.VITE_GLOB_API_URL}/upload/file`)
let isLoopIn = false
let timer: any = null
const aspect = ref('9:16')
const model = ref('MJ')
const version = ref('5.2')
const style = ref(0)
const quality = ref('1')
const stylize = ref(100)
const chaos = ref(0)
const prompt = ref('')
const noPrompt = ref('')
const drawList: any = ref([])
const countQueue = ref(0)
const refreshLoading = ref(false)
const associateLoading = ref(false)
const translateLoading = ref(false)
const promptList = ref<PromptItem[]>([])
const size = ref(12)
const nextOpenCarryOptions = ref(true) // 下次打开自动携带参数
const totalCount = ref(0)
const carryOptions = ref(1)
const submitDisabled = computed(() => {
  return !prompt.value || associateLoading.value || translateLoading.value || translateNoLoading.value
})

const dataBase64 = ref('')
let curFile: File | null

watch(isLogin, async (newVal, oldVal) => {
  if (newVal && !oldVal)
    await queryDrawResult()
})

const isMore = computed(() => totalCount.value > size.value)

const sizeList = [
  { aspect: '1:1', width: '100%', height: '100%' },
  { aspect: '4:3', width: '100%', height: '75%' },
  { aspect: '3:4', width: '75%', height: '100%' },
  { aspect: '16:9', width: '100%', height: '57%' },
  { aspect: '9:16', width: '57%', height: '100%' },
]

const styleOptions = [
  { label: '默认风格', value: 0 },
  { label: '表现力风格', value: 'expressive' },
  { label: '可爱风格', value: 'cute' },
  { label: '景观风格', value: 'scenic' },
]

const qualityOptions = [
  { label: '普通', value: '.25' },
  { label: '一般', value: '.5' },
  { label: '高清', value: '1' },
  { label: '超高清', value: '2' },
]

const versionOptions = computed(() => {
  if (model.value === 'MJ') {
    return [
      { label: '5.2', value: '5.2' },
      { label: '5.1', value: '5.1' },
      { label: '5', value: '5' },
      { label: '4', value: '4' }]
  }
  if (model.value === 'NIJI') {
    return [
      { label: '5', value: '5' },
      { label: '4', value: '4' },
    ]
  }
  return []
})

const modelList = [
  { name: 'MJ', img: mjImg, val: 'mj' },
  { name: 'NIJI', img: nijiImg, val: 'niji' },
]

const activeAspect = computed(() => (item: string) => {
  return aspect.value === item
})

const activeModel = computed(() => (item: string) => {
  return model.value === item
})

function handleFileSelect(event: any) {
  const file = event?.target?.files[0]
  handleSetFile(file)
}

function handleDrop(event: any) {
  event.preventDefault()
  const file = event.dataTransfer.files[0]
  handleSetFile(file)
}

async function handleSetFile(file: File) {
  curFile = file
  const reader = new FileReader()
  reader.onload = (event: any) => {
    dataBase64.value = event.target?.result as string
  }
  reader.readAsDataURL(file)
}


async function hanleQueryPrompts(){
	const res: any = await fetchMidjourneyPromptList()
	promptList.value = res.data.filter( (item: any) => item.status)
}

async function queryAllDrawList() {
  const res: ResData = await fetchMidjourneyDrawList({ page: 1, size: size.value })
  const { rows, countQueue: queueCount, count } = res.data
  drawList.value = rows || []
  totalCount.value = count
  countQueue.value = queueCount || 0
}

async function drawLike(){
	const id = route.query.mjId
	if(!id) return;
	const res: ResData = await fetchMidjourneyFullPrompt({id})
	if(!res.success) return
	prompt.value = res.data
	carryOptions.value = 0
	nextOpenCarryOptions.value =  true
}

/* 翻译prompt */
async function handleFanyiPrompt() {
  if (!prompt.value)
    return ms.warning('请输入描述词！')
  translateLoading.value = true
  try {
		const Interface = Number(authStore.globalConfig.mjUseBaiduFy) === 1 ?  fetchTranslateAPI : fetchGetMjPromptFanyiApi
		const params: any =  Number(authStore.globalConfig.mjUseBaiduFy) === 1 ? { text: prompt.value } : { prompt: prompt.value }
    const res: ResData = await Interface(params)
    if (!res.success)
      return ms.error('翻译失败了！')
    prompt.value = res.data
    translateLoading.value = false
  }
  catch (error) {
    translateLoading.value = false
  }
}
const translateNoLoading = ref(false)
/* 翻译不需要的元素 */
async function handleFanyiNoPrompt() {
  if (!noPrompt.value)
    return ms.warning('请输入描述词！')
		translateNoLoading.value = true
  try {
		const Interface = Number(authStore.globalConfig.mjUseBaiduFy) === 1 ?  fetchTranslateAPI : fetchGetMjPromptFanyiApi
		const params: any =  Number(authStore.globalConfig.mjUseBaiduFy) === 1 ? { text: noPrompt.value } : { prompt: noPrompt.value }
    const res: ResData = await Interface(params)
    if (!res.success)
      return ms.error('翻译失败了！')
    noPrompt.value = res.data
    translateNoLoading.value = false
  }
  catch (error) {
    translateNoLoading.value = false
  }
}

/* 联想描述词 */
async function handleAssociatePrompt() {
  if (!prompt.value)
    return ms.warning('请输入描述词！')
  associateLoading.value = true
  try {
    const res: ResData = await fetchGetMjPromptAssociateApi({ prompt: prompt.value })
    if (!res.success)
      return ms.error('联想失败了')
    prompt.value = res.data
    associateLoading.value = false
  }
  catch (error) {
    associateLoading.value = false
  }
}

/* 检测是否需要翻译 */
function hasChinese(str: string) {
  const reg = /[\u4E00-\u9FA5]/g
  return reg.test(str)
}


/* 移除用户自己的指令 */
function removeParameters(str: string) {
  const regex = /--\w+\s\S+/g
  return str.replace(regex, '')
}

/* 格式化绘画参数 */
function formatParams() {
  if (!carryOptions.value)
    return ''
  let formatPropmpt = ''
  /* 不需要的内容 */
  noPrompt.value && (formatPropmpt += ` --no ${noPrompt.value}`)
  /* 模型+版本 */
  if (model.value === 'MJ' && version.value) {
    formatPropmpt += ` --v ${version.value}`
    formatPropmpt += ` --s ${stylize.value}`
  }
  if (model.value === 'NIJI' && version.value) {
    formatPropmpt += ` --niji ${version.value}`
    /* niji5 拥有的风格 */
    style.value && (formatPropmpt += ` --style ${style.value}`)
  }
  /* 尺寸 */
  formatPropmpt += ` --ar ${aspect.value}`
  /* chaos (混乱) */
  formatPropmpt += ` --c ${chaos.value}`
  /* quality */
  formatPropmpt += ` --q ${quality.value}`
  return formatPropmpt
}

/* 上传图片 */
async function uploadImg() {
  const form = new FormData()
  curFile && form.append('file', curFile)
  const res = await axios.post(uploadUrl.value, form, { headers: { 'Content-Type': 'multipart/form-data' } })
  return res?.data?.data
}

/* 修改提示词 */
function handleSelectPrompt(item: any){
	const { prompt: text, aspect: size, isCarryParams  } = item
	prompt.value = text
	size && (aspect.value = size)
	carryOptions.value = isCarryParams ? 1 : 0
}


function checkHasChinese(){
	const isHasPromptChinese = hasChinese(prompt.value)
	const isHasNoPromptChinese = hasChinese(noPrompt.value)
	if(isHasPromptChinese || isHasNoPromptChinese){
		const d = dialog.warning({
			title: '温馨提示',
			content: '您的提示词中包含中文、绘画AI可能无法识别您的中文、我们建议您翻译后进行绘画得到更准确的结果、请问需要翻译后提交么？',
			positiveText: '翻译提示词',
			negativeText: '不需要',
			onPositiveClick: async () => {
				d.loading = true
				const task = []
				isHasPromptChinese && task.push(handleFanyiPrompt())
				isHasNoPromptChinese && task.push(handleFanyiNoPrompt())
				await Promise.all(task)
				handleSubmit()
			},
			onNegativeClick: () => {
				handleSubmit()
			}
		})
	}else{
		handleSubmit()
	}
}

/* 提交绘制任务|图生图 */
async function handleSubmit() {
  let imgUrl = ''
  if (dataBase64.value || curFile)
    imgUrl = await uploadImg()

  const extraParam = formatParams()

  /* 如果使用我们的参数 则去掉用户自己的 */
  if (carryOptions.value)
    prompt.value = removeParameters(prompt.value)

  await fetchDrawTaskAPI({ prompt: prompt.value, imgUrl, extraParam })
  curFile && (curFile = null)
  dataBase64.value = ''
	if(nextOpenCarryOptions.value){
		carryOptions.value = 1
		nextOpenCarryOptions.value = false
	}
  ms.success('提交绘制任务成功、请等待绘制结束！')
	if(authStore.token){
		await refreshUserInfo()
	}
  !isLoopIn && queryDrawResult()
}



/* 轮询查询结果 */
async function queryDrawResult() {
  isLoopIn = true
  const res: ResData = await fetchMidjourneyDrawList({ page: 1, size: size.value })
  const { rows, countQueue: queueCount, count } = res.data
  drawList.value = rows || []
  totalCount.value = count
  countQueue.value = queueCount || 0
  const curDrawTask = drawList.value.filter((item: any) => [1, 2].includes(item.status))
  if (curDrawTask.length)
    timer = setTimeout(() => queryDrawResult(), 3000)

  else
    isLoopIn = false
}

onBeforeUnmount(() => {
  clearTimeout(timer)
})

/* 当前绘制中的任务 */
const curDrawTask = computed(() => {
  return drawList.value.filter((item: any) => [1, 2].includes(item.status))
})




/* 前往市场 */
function readMore() {
  router.push('/market')
}

/* 复制 */
function usePrompt(item: any) {
  const { fullPrompt } = item
	carryOptions.value  = 0
	prompt.value = fullPrompt
	nextOpenCarryOptions.value = true
  // copyText({ text: fullPrompt })
  // ms.success('复制prompt完成！')
}

function setModel(name: string) {
  model.value = name
  if (name === 'MJ')
    version.value = '5.1'

  if (name === 'NIJI')
    version.value = '5'
}


async function refreshUserInfo() {
  refreshLoading.value = true
  try {
    await authStore.getUserInfo()
    refreshLoading.value = false
  }
  catch (error) {
    refreshLoading.value = false
  }
}



onMounted(() => {
  queryDrawResult()
	drawLike()
	hanleQueryPrompts()
  const container: any = document.getElementById('footer')
  const observer = new IntersectionObserver((entries, observer) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        if (isMore.value) {
          size.value = size.value + 12
          queryAllDrawList()
        }
      }
    })
  })
  observer.observe(container)
})
</script>

<template>
  <div class="grow flex h-screen flex-col lg:pt-0">
    <div class="flex grow flex-col sm:flex-row h-full">
      <div class="p-4 sm:pt-6 bg-[#f8f8f8]  p-4 dark:bg-[#18181c] overflow-y-auto w-full sm:w-[20rem]  shrink-0 border-r-2 border-[#ffffff17]">
        <div class="mt-4 text-sm flex items-center">
          <div class="text-sm mr-1">
            图片尺寸
          </div>

          <div data-tool-target="tooltip-default">
            <NTooltip placement="right-end" trigger="hover">
              <template #trigger>
                <SvgIcon icon="ri:error-warning-line" class="text-base" />
              </template>
              参数释义：生成图片尺寸比例
            </NTooltip>
          </div>
        </div>
        <div class="flex mt-2 py-1 pb-2 space-x-1 overflow-x-auto justify-between scrollbar-none ">
          <button
            v-for="(item, index) in sizeList"
            :key="index"
            class=" flex-1 p-[2px] rounded-md "
            @click="aspect = item.aspect"
          >
            <div class=" border-2   border-gray-300 box-borde rounded-md dark:bg-black flex flex-col items-center" :class="[activeAspect(item.aspect) ? 'aspect-active' : '', isMobile ? 'py-3' : 'py-2']">
              <div class="flex items-center justify-center w-6 h-6">
                <div class="border-gray-300 rounded border-2 " :class="[activeAspect(item.aspect) ? 'aspect-active' : '']" :style="{ width: item.width, height: item.height }" />
              </div>
              <div class="mt-2 text-center text-xs leading-none text-current">
                {{ item.aspect }}
              </div>
            </div>
          </button>
        </div>

        <!-- 模型 -->
        <div class="mt-4 text-sm flex items-center">
          <div class="mr-1">
            模型选择
          </div>
          <div data-tool-target="tooltip-default">
            <NTooltip placement="right-end" trigger="hover">
              <template #trigger>
                <SvgIcon icon="ri:error-warning-line" class="text-base" />
              </template>
              <div style="width: 240px">
                <p>MJ: 偏真实通用模型</p>
                <p>NIJI:  偏动漫风格、适用于二次元模型</p>
              </div>
            </NTooltip>
          </div>
        </div>
        <ul class="mt-2 flex justify-between">
          <li
            v-for="(item, index) in modelList"
            :key="index"
            class="flex border-[3px] border-transparent justify-center items-center rounded-md m-1 m-bg-gradient"
            :class="[activeModel(item.name) ? 'model-active' : '']"
            @click="setModel(item.name)"
          >
            <button class="relative w-full h-full dark:bg-black  rounded" type="button">
              <div class="absolute w-full h-full flex justify-center items-center">
                <div class="text-2xl text-white font-bold absolute left-5 top-1">
                  {{ item.name }}
                </div>
              </div><img :src="item.img" class="rounded aspect-[3/1] w-full object-cover">
            </button>
          </li>
        </ul>
        <div class="mt-4">
          <div class="mt-2 flex justify-between items-center space-x-2 text-xs">
            <span class="w-[65px] block text-sm">版本</span>
            <span class="flex-1">
              <NSelect v-model:value="version" size="small" :options="versionOptions" />
            </span>
          </div>
          <div v-if="model === 'NIJI'" class="mt-2 flex justify-between items-center space-x-2 text-xs">
            <span class="w-[65px] block text-sm">风格</span>
            <span class="flex-1">
              <NSelect v-model:value="style" size="small" :options="styleOptions" />
            </span>
          </div>
          <div class="block text-sm mt-2 flex items-center">
            参数
            <NTooltip placement="right-end" trigger="hover">
              <template #trigger>
                <SvgIcon icon="ri:error-warning-line" class="text-base ml-2" />
              </template>
              <div style="width: 240px">
                <p>合理使用参数绘制更为理想的结果！</p>
              </div>
            </NTooltip>
          </div>
          <div class="mt-3 flex justify-between items-center space-x-2 text-xs">
            <span class="w-[65px] block text-sm">品质</span>
            <span class="flex-1">
              <NSelect v-model:value="quality" size="small" :options="qualityOptions" />
            </span>
          </div>
          <div class="mt-3 flex justify-between items-center space-x-2 text-xs">
            <span class="w-[65px] block text-sm">混乱</span>
            <span class="flex-1">
              <NInputNumber v-model:value="chaos" :min="0" :max="100" size="small" />
            </span>
            <NTooltip placement="right-end" trigger="hover">
              <template #trigger>
                <SvgIcon icon="ri:error-warning-line" class="text-base ml-2" />
              </template>
              <div style="width: 270px">
                <p>取值范围：0-100、 --chaos 或 --c</p>
                <p>混乱级别，可以理解为让AI天马行空的空间</p>
                <p>值越小越可靠、默认0最为精准</p>
              </div>
            </NTooltip>
          </div>

          <div v-if="model === 'MJ'" class="mt-3 flex justify-between items-center space-x-2 text-xs">
            <span class="w-[65px] block text-sm">风格化</span>
            <span class="flex-1">
              <NInputNumber v-model:value="stylize" :min="0" :max="1000" size="small" />
            </span>
            <NTooltip placement="right-end" trigger="hover">
              <template #trigger>
                <SvgIcon icon="ri:error-warning-line" class="text-base ml-2" />
              </template>
              <div style="width: 270px">
                <p>风格化：--stylize 或 --s，范围 1-1000</p>
                <p>参数释义：数值越高，画面表现也会更具丰富性和艺术性</p>
              </div>
            </NTooltip>
          </div>

          <div class="block text-sm mt-2 flex items-center">
            设定
          </div>
          <div class="mt-3 flex justify-between items-center space-x-2 text-xs">
            <span class="w-[65px] block text-sm">携带参数</span>
            <span class="flex-1">
              <NSwitch v-model:value="carryOptions" size="small" :checked-value="1" :unchecked-value="0" />
            </span>
            <NTooltip placement="right-end" trigger="hover">
              <template #trigger>
                <SvgIcon icon="ri:error-warning-line" class="text-base ml-2" />
              </template>
              <div style="width: 240px">
                <p>是否自动携带参数</p>
                <p>打开：携带上述我们配置的参数</p>
                <p>关闭：使用指令中的我们自定义的参数</p>
              </div>
            </NTooltip>
          </div>
        </div>

        <div class="mt-5">
          <div class="block text-base">
            以图生图
          </div>
          <div class="ant-spin-nested-loading css-4fssqp mt-5">
            <div class="ant-spin-container">
              <div class="mt-2 flex justify-center items-center dark:bg-black p-5 rounded-md">
                <label v-if="!dataBase64" for="upload-file">
                  <div class="upload cursor-pointer" @dragover.prevent @dragenter.prevent @dragleave.prevent @drop="handleDrop">
                    <input id="upload-file" type="file" accept=".png, .jpg, .jpeg" style="display: none;" @change="handleFileSelect($event)">
                    <div class="upload-container">
                      <img
                        class="mx-auto py-2 w-11"
                        src=""
                      >
                      <p class="mt-3">点击或拖拽一个图片到这里作为输入</p>
                      <p class="text-center dark:text-[#ffffff73]">支持PNG和JPG格式</p>
                    </div>
                  </div>

                </label>
                <div v-if="dataBase64" class="w-full h-full relative">
                  <img :src="dataBase64" alt="">
                  <img class="absolute bottom-1 right-1 cursor-pointer" src="" @click="dataBase64 = null">
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="mt-5">
          <div class="block  flex justify-between">
            <span class="text-base py-1">钱包余额(<b class="text-[#3076fd]">{{ sumDrawMjCount || 0 }}</b> 积分)</span>
            <span class="flex items-center">
              <NButton text size="tiny" type="primary" :loading="refreshLoading" @click="refreshUserInfo">刷新</NButton>
              <NTooltip placement="right-end" trigger="hover">
                <template #trigger>
                  <SvgIcon icon="ri:error-warning-line" class="text-base ml-2" />
                </template>
                绘画账户信息
              </NTooltip>
            </span>
          </div>
          <div class="mt-3  space-y-1 items-center text-[#3076fd] ">
            <div class="flex justify-between">
              <span class="w-[120px] block text-sm">绘画单次消耗：</span>
              <span class="text-sm pr-2">
                4积分
              </span>
            </div>
						<div class="flex justify-between">
              <span class="w-[120px] block text-sm">图生图单次消耗：</span>
              <span class="text-sm pr-2">
                4积分
              </span>
            </div>
            <div class="flex justify-between">
              <span class="w-[120px] block text-sm">放大单次消耗：</span>
              <span class="text-sm pr-2">
                1积分
              </span>
            </div>
          </div>
        </div>
      </div>

      <!-- 右 -->
      <div class="h-full flex-1" :class="[isMobile ? '' : 'overflow-y-auto overflow-hidden']">
        <div class="m-auto max-w-screen-4xl">
          <div class="space-y-6 p-4">
            <h3 class="text-lg sm:text-2xl font-bold leading-6 ">
              Midjourney
            </h3>
						<!-- <p>图生图：生成类似风格或类型图像；图生文：上传一张图片生成对应的提示词；融图：融合图片风格</p> -->
            <div>
              <div class="flex justify-between items-end">
                <b>你想生成什么图像?</b>
                <NSpace>
                  <NButton type="primary" :loading="translateLoading" @click="handleFanyiPrompt">
                    <template #icon>
                      <SvgIcon icon="ri:translate" class="text-base" />
                    </template>
                    翻译
                  </NButton>
                  <NButton type="primary" :loading="associateLoading" @click="handleAssociatePrompt">
                    <template #icon>
                      <SvgIcon icon="material-symbols:mindfulness-outline-rounded" class="text-base" />
                    </template>
                    联想
                  </NButton>
                </NSpace>
              </div>
              <div class="mt-4">
                <NInput
                  v-model:value="prompt"
                  type="textarea"
                  :disabled="associateLoading || translateLoading"
                  :autosize="{
                    minRows: 4,
                    maxRows: 6,
                  }"
                  placeholder="例如: A cute little cat (Midjourney对中文描述词有一定限制、我们建议您点击右侧翻译将您的描述词转为英文再进行提交、联想则是会将您的描述词交由GPT让其发挥想象空间为您在此基础创建更为详细的描述！)"
                />
                <div class="mt-4" v-if="Number(authStore.globalConfig.mjHideNotBlock) !== 1">
                  <div class="mb-3 flex justify-between items-end">
                    <b>不需要的元素</b>
                    <NButton type="primary" :loading="translateNoLoading" @click="handleFanyiNoPrompt">
                      <template #icon>
                        <SvgIcon icon="ri:translate" class="text-base" />
                      </template>
                      翻译
                    </NButton>
                  </div>
                  <NInput
                    v-model:value="noPrompt"
                    type="textarea"
										:rows="1"
                    placeholder="例：生成房间图片、但是不要床、你可以填bed！"
                  />
                </div>
              </div>
							<div class="w-full dark:bg-transparent"  :class="isMobile ? 'py-3' : 'py-6'" v-if="promptList.length">
									<NScrollbar  x-scrollable>
										<div class="flex items-center space-x-3 whitespace-nowrap pb-[15px]">
											<n-button size="small" v-for="(item,index) in promptList" :key="index" @click="handleSelectPrompt(item)">
												{{ item.title }}
											</n-button>
										</div>
									</NScrollbar>
								</div>
              <div class="mt-3">
                <NButton type="primary" :loading="false" :disabled="submitDisabled" @click="checkHasChinese">
                  <template #icon>
                    <SvgIcon icon="ri:ai-generate" class="text-base" />
                  </template>
                  提交绘画任务
                </NButton>
              </div>
            </div>
          </div>

          <div class="space-y-2 p-4">
						<div   v-if="Number(authStore.globalConfig.mjHideWorkIn) !== 1">
							<div class="mt-6 mb-4 flex flex-col">
								<span class="text-xl font-bold flex items-end">
									<b>工作中的内容</b>
									<span v-if="countQueue" class="text-xs font-family ml-2">当前系统进行中任务[{{ countQueue }}]</span>
								</span>
							</div>
							<div v-if="!curDrawTask.length" class="h-[10vh] flex flex-col justify-center items-center text-gray-500 relative">
								<img class="w-18" :src="marketImg">
								<span class="mt-4">
									<NButton text size="small" @click="readMore">点击前往市场看看别人的作品吧！</NButton>
								</span>
							</div>

							<div v-if="curDrawTask.length" class="h-[10vh] flex flex-col justify-center items-center text-gray-500 relative">
								<div class="w-56 h-14 relative">
									<Loading :text-color="loadingTextColor" />
								</div>
								<p class="mb-3">
									当前{{ curDrawTask.length }}个任务正在进行中、请耐心等候绘制完成、您可以前往其他页面稍后回来查看结果！
								</p>
							</div>
						</div>
            <!-- working -->
            <div class="min-h-[500px] mt-5">
              <div class="mt-6 mb-10 flex flex-col">
                <span class="text-xl font-bold ">我的绘图 <span class="text-base text-[gray]">[{{ drawList.length }}]</span></span>
                <span class="mt-2 text-xs font-bold text-[#444]">点击下面的编号按钮以获取升级版（U: 放大图片更细节）或变化版（V: 在此基础上变体）</span>
              </div>
              <div v-if="!drawList || !drawList.length" class=" w-full py-28">
                <img class=" mx-auto" src="" alt="">
              </div>

              <div v-if="drawList && drawList.length">
                <div class="grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4 4xl:grid-cols-5 gap-4">
									<cardItem v-for="item in drawList" :key="item.id" @queryData="queryDrawResult"  :drawItemInfo="item" />
                </div>
              </div>
            </div>

            <div id="footer" ref="containerRef" />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="less">
.aspect-active{
	border: 2px solid #3074F8FF;
  color: #3074F8FF;
}

.model-active{
	border: 3px solid #3074F8FF;
}

.upload{
  border: 1px dashed #424242;
  font-size: 12px;
  border-radius: 8px;
  padding: 14px;
  &:hover{
    border: 1px dashed #3074F8FF;
  }
}
</style>
